package com.zifan.yygh.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zifan.common.result.ResultCodeEnum;
import com.zifan.yygh.exception.YyghException;
import com.zifan.yygh.model.hosp.Department;
import com.zifan.yygh.model.hosp.HospitalSet;
import com.zifan.yygh.repository.DepartmentRepository;
import com.zifan.yygh.service.DepartmentService;
import com.zifan.yygh.service.HospitalSetService;
import com.zifan.yygh.utils.MD5;
import com.zifan.yygh.vo.hosp.DepartmentVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Zifan
 * @date 2021年09月27日19:57
 */
@Service
@SuppressWarnings("all")
public class DepartmentServiceImpl implements DepartmentService {

    @Autowired
    private DepartmentRepository departmentRepository;
    @Autowired
    private HospitalSetService setService;

    /**
     * 保存科室信息
     */
    @Override
    public void saveDepartment(Map<String, Object> paramMap) {
        //map转成对象
        Department department = JSON.parseObject(JSON.toJSONString(paramMap), Department.class);

        //校验签名
        String sign = (String) paramMap.get("sign");

        //获取数据库中医院设置信息的签名
        QueryWrapper<HospitalSet> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(HospitalSet::getHoscode, department.getHoscode())
                .select(HospitalSet::getSignKey);
        String signKey = setService.getOne(queryWrapper).getSignKey();

        //校验签名
        if (!StrUtil.equals(sign, MD5.encrypt(signKey))) {
            throw new YyghException(ResultCodeEnum.SIGN_ERROR);
        }

        //从mongo中查数据
        Department resDepat = departmentRepository.getDepartmentByHoscodeAndDepcode(department.getHoscode(), department.getDepcode());
        if (ObjectUtil.isNull(resDepat)) {
            //新增
            department.setCreateTime(new Date());
            department.setUpdateTime(new Date());
            department.setIsDeleted(0);


        } else {
            //修改

            //修改首先要设置ID
            department.setId(resDepat.getId());
            department.setIsDeleted(resDepat.getIsDeleted());
            department.setUpdateTime(new Date());
        }

        //执行保存
        departmentRepository.save(department);

    }

    /**
     * 分页获取科室信息
     */
    @Override
    public Page<Department> getDepartmentList(Map<String, Object> paramMap) {
        //todo 签名校验，暂时不做

        //获取分页信息 分页信息设计的很tm逆天，如果第一页就传空，否则就传分页信息
        //每页大小
        Integer limit = ObjectUtil.isEmpty(paramMap.get("limit")) ? 10 : Integer.parseInt((String) paramMap.get("limit"));
        //当前页
        Integer page = ObjectUtil.isEmpty(paramMap.get("page")) ? 1 : Integer.parseInt((String) paramMap.get("page"));

        //获取医院编号并校验
        String hoscode = (String) paramMap.get("hoscode");
        if (StrUtil.isEmpty(hoscode)) {
            throw new YyghException(ResultCodeEnum.PARAM_ERROR);
        }
        //获取科室编号
        String depcode = (String) paramMap.get("depcode");

        //封装成科室实体类（因为mongo查询的时候需要用到）
        Department department = new Department();
        department.setHoscode(hoscode);
        department.setDepcode(depcode);

        //配置条件查询语句
        ExampleMatcher exampleMatcher = ExampleMatcher.matching() //构建对象条件匹配器
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) //改变默认字符串的匹配方式：模糊查询
                .withIgnoreCase(true);//忽略大小写
        //创建查询实例，类似mybatisplus中的querywraper
        Example<Department> example = Example.of(department, exampleMatcher);

        //配置排序方式
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");

        //配置分页信息
        PageRequest pageRequest = PageRequest.of(page - 1, limit, sort);

        //查询并返回
        return departmentRepository.findAll(example, pageRequest);
    }

    /**
     * 根据id删除科室信息
     */
    @Override
    public void removeDepartment(Map<String, Object> paramMap) {
        //todo 签名校验
        String hoscode = (String) paramMap.get("hoscode");
        //必填
        String depcode = (String) paramMap.get("depcode");
        if (StrUtil.isEmpty(hoscode)) {
            throw new YyghException(ResultCodeEnum.PARAM_ERROR);
        }
        //先根据医院编号和部门编号查询
        Department department = departmentRepository.getDepartmentByHoscodeAndDepcode(hoscode, depcode);
        if (ObjectUtil.isNotNull(department)) {
            //删除
            departmentRepository.deleteById(department.getId());
        } else {
            throw new YyghException(ResultCodeEnum.PARAM_ERROR);
        }
    }

    /**
     * 根据医院编号，查询医院所有科室列表
     */
    @Override
    public List<DepartmentVo> findDeptTree(String hoscode) {
        ArrayList<DepartmentVo> resList = new ArrayList<>();

        //查询当前医院编号下所有的科室信息,因为使用的mongoDB，所以再详细写一遍，不怎么熟练
        Department departmentQuery = new Department();
        departmentQuery.setHoscode(hoscode);
        Example<Department> example = Example.of(departmentQuery);
        List<Department> departments = departmentRepository.findAll(example);
        //之后就是对数据的封装了，方法一大堆。视频中的方法有点逆天，这里打算自己写
        //先进行分局，分组后，k是Bigcode,v是属于该bigcode所有的数组
        Map<String, List<Department>> map = departments.stream().collect(Collectors.groupingBy(Department::getBigcode));
        //接下来对map进行遍历 这是map遍历的一种方式
        for (Map.Entry<String, List<Department>> entry : map.entrySet()) {
            //准备一个DepartmentVo
            DepartmentVo departmentVo = new DepartmentVo();
            //开始封装数据
            //这是最外层的部门代码，直接取value
            departmentVo.setDepcode(entry.getKey());
            //最外层，相当于父级的名字，就是list中的bigname，因为都是相同的，所以get0就行
            departmentVo.setDepname(entry.getValue().get(0).getBigname());
            //然后开始封装子节点
            //准备一个子节点的vo对象
            DepartmentVo departmentVoChild = new DepartmentVo();
            //准备一个收集子节点的集合
            List<DepartmentVo> departmentVoChilds = new ArrayList<>();
            //需要一个循环
            for (Department department : entry.getValue()) {
                departmentVoChild.setDepcode(department.getDepcode());
                departmentVoChild.setDepname(department.getDepname());
                departmentVoChilds.add(departmentVoChild);
                //清除数据，开始下一个循环
                departmentVoChild = new DepartmentVo();
            }
            //然后设置最终的children
            departmentVo.setChildren(departmentVoChilds);
            //循环结束后最终实体添加该对象
            resList.add(departmentVo);
            //清除数据，开始下一个循环
            departmentVo = new DepartmentVo();
        }

        return resList;
    }

    /**
     * 根据科室编号，和医院编号，查询科室名称
     */
    @Override
    public String getDepName(String hoscode, String depcode) {
        Department department = departmentRepository.getDepartmentByHoscodeAndDepcode(hoscode, depcode);
        if (ObjectUtil.isNotNull(department)) {
            return department.getDepname();
        }
        return null;

    }
}
